package com.atguigu.gulimall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.common.to.SocialUser;
import com.atguigu.common.utils.HttpUtils;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.gulimall.member.dao.MemberDao;
import com.atguigu.gulimall.member.entity.MemberEntity;
import com.atguigu.gulimall.member.entity.MemberLevelEntity;
import com.atguigu.gulimall.member.exception.PhoneExistException;
import com.atguigu.gulimall.member.exception.UserNameExistException;
import com.atguigu.gulimall.member.service.MemberLevelService;
import com.atguigu.gulimall.member.service.MemberService;
import com.atguigu.gulimall.member.vo.MemberLoginVO;
import com.atguigu.gulimall.member.vo.MemberRegisterVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author wenchao.long
 */
@Service("memberService")
@AllArgsConstructor
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    private final MemberLevelService memberLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(MemberRegisterVO memberRegisterVO) {

        MemberLevelEntity levelEntity = memberLevelService.getDefaultLevel();

        // 校验用户名和手机号是否唯一
        String phone = memberRegisterVO.getPhone();
        String userName = memberRegisterVO.getUserName();
        // 为了让controller能感知异常 异常机制
        checkPhoneUnique(phone);
        checkUserNameUnique(userName);

        // 密码进行加密
        String password = memberRegisterVO.getPassword();
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

        MemberEntity entity = MemberEntity.builder()
                .levelId(levelEntity.getId())
                .mobile(phone)
                .username(userName)
                .nickname(userName)
                .password(passwordEncoder.encode(password))
                .build();

        save(entity);
    }

    @Override
    public MemberEntity login(MemberLoginVO vo) {
        String loginacct = vo.getLoginacct();
        String password = vo.getPassword();

        // 1. 去数据库查询
        MemberEntity memberEntity = getOne(Wrappers.<MemberEntity>lambdaQuery()
                .eq(MemberEntity::getUsername, loginacct)
                .or()
                .eq(MemberEntity::getMobile, loginacct)
        );
        if (memberEntity == null) {
            return null;
        }
        String oldPassword = memberEntity.getPassword();

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        boolean matches = passwordEncoder.matches(oldPassword, password);
        return matches ? memberEntity : null;
    }

    @Override
    public MemberEntity login(SocialUser user) {
        // 登录和注册合并逻辑
        String uid = user.getUid();
        String accessToken = user.getAccessToken();
        long expiresIn = user.getExpiresIn();

        // 1. 判断当前社交用户是否已经登录过系统
        MemberEntity memberEntity = getOne(Wrappers.<MemberEntity>lambdaQuery()
                .eq(MemberEntity::getSocialUid, uid));
        if (memberEntity != null) {
            // 这个用户已经注册 修改他的令牌信息
            memberEntity.setAccessToken(accessToken);
            memberEntity.setExpiresIn(expiresIn);
            updateById(memberEntity);
            return memberEntity;
        }

        MemberLevelEntity levelEntity = memberLevelService.getDefaultLevel();

        MemberEntity member = MemberEntity.builder()
                .accessToken(accessToken)
                .socialUid(uid)
                .expiresIn(expiresIn)
                .levelId(levelEntity.getId())
                .build();
        try {
            Map<String, String> querys = new HashMap<>(10);
            querys.put("access_token", accessToken);
            querys.put("uid", user.getUid());
            HttpResponse response = HttpUtils.doGet("https://api.weibo.com", "/2/users/show.json",
                    "GET", new HashMap<>(10), querys);
            if (response.getStatusLine().getStatusCode() == HttpStatus.OK.value()) {
                String json = EntityUtils.toString(response.getEntity());
                JSONObject jsonObject = JSON.parseObject(json);
                // 昵称
                String name = jsonObject.getString("name");
                String gender = jsonObject.getString("gender");

                member.setNickname(name);
                member.setGender("m".equalsIgnoreCase(gender) ? 1 : 0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 2. 没有查到当前社交用户对应的记录  注册
        save(member);
        return member;
    }

    private void checkPhoneUnique(String phone) throws PhoneExistException {
        int count = count(Wrappers.<MemberEntity>lambdaQuery()
                .eq(MemberEntity::getMobile, phone));
        if (count > 0) {
            throw new PhoneExistException();
        }
    }

    private void checkUserNameUnique(String userName) throws UserNameExistException {
        int count = count(Wrappers.<MemberEntity>lambdaQuery()
                .eq(MemberEntity::getUsername, userName));
        if (count > 0) {
            throw new UserNameExistException();
        }
    }

}
